/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     MetaMatrix, Inc - repackaging and updates for use as a metadata store
 *******************************************************************************/
package org.teiid.internal.core.index;

import java.io.IOException;
import java.util.ArrayList;

public class FileListBlock extends Block {

    protected int offset= 0;
    protected String prevPath= null;
    protected String[] paths= null;

    public FileListBlock(int blockSize) {
        super(blockSize);
    }
    /**
     * add the name of the indexedfile to the buffr of the field.
     * The name is not the entire name of the indexedfile, but the
     * difference between its name and the name of the previous indexedfile ...
     */
    public boolean addFile(IndexedFile indexedFile) {
        int offset= this.offset;
        if (isEmpty()) {
            field.putInt4(offset, indexedFile.getFileNumber());
            offset += 4;
        }
        String path= indexedFile.getPath();
        int prefixLen= prevPath == null ? 0 : Util.prefixLength(prevPath, path);
        int sizeEstimate= 2 + 2 + (path.length() - prefixLen) * 3;
        if (offset + sizeEstimate > blockSize - 2)
            return false;
        field.putInt2(offset, prefixLen);
        offset += 2;
        char[] chars= new char[path.length() - prefixLen];
        path.getChars(prefixLen, path.length(), chars, 0);
        offset += field.putUTF(offset, chars);
        this.offset= offset;
        prevPath= path;
        return true;
    }
    public IndexedFile getFile(int fileNum) throws IOException {
        IndexedFile resp= null;
        try {
            String[] paths= getPaths();
            int i= fileNum - field.getInt4(0);
            resp= new IndexedFile(paths[i], fileNum);
        } catch (Exception e) {
            //fileNum too big
        }
        return resp;
    }
    /**
     * Creates a vector of paths reading the buffer of the field.
     */
    protected String[] getPaths() throws IOException {
        if (paths == null) {
            ArrayList v= new ArrayList();
            int offset= 4;
            char[] prevPath= null;
            for (;;) {
                int prefixLen= field.getUInt2(offset);
                offset += 2;
                int utfLen= field.getUInt2(offset);
                char[] path= field.getUTF(offset);
                offset += 2 + utfLen;
                if (prefixLen != 0) {
                    char[] temp= new char[prefixLen + path.length];
                    System.arraycopy(prevPath, 0, temp, 0, prefixLen);
                    System.arraycopy(path, 0, temp, prefixLen, path.length);
                    path= temp;
                }
                if (path.length == 0)
                    break;
                v.add(new String(path));
                prevPath= path;
            }
            paths= new String[v.size()];
            v.toArray(paths);
        }
        return paths;
    }
    public boolean isEmpty() {
        return offset == 0;
    }
    public void reset() {
        offset= 0;
        prevPath= null;
    }
}
